import { Injectable } from '@nestjs/common';
import { UserService } from "@/modules/user/user.service";
import { JwtService } from "@nestjs/jwt";
import { RedisService } from "@/shared/redis.service";
import { createHash } from 'crypto';
import { CustomException, ErrorCode } from "@/common/exceptions/custom.exception";

@Injectable()
export class AuthService {
  constructor(
    private userService: UserService,
    private jwtService: JwtService,
    private redisService: RedisService,
  ) {}

  //验证邮件
  async validateEmail(email: string, password: string) {
    const user = await this.userService.findByEmail(email);
    if (user) {
      const hashedPassword = createHash('md5').update(password).digest('hex');
      if (hashedPassword === user.password) {
        const { password, ...result } = user;
        return result;
      }
    }
    return null;
  }

  //验证手机号
  async validatePhone(phone: string, password: string) {
    const user = await this.userService.findByEmail(phone);
    if (user) {
      const hashedPassword = createHash('md5').update(password).digest('hex');
      if (hashedPassword === user.password) {
        const { password, ...result } = user;
        return result;
      }
    }
    return null;
  }

  //登录
  async login(userData: any, req: Request) {
    const { id, status } = userData;
    if (!status) throw new CustomException(ErrorCode.ERR_11007);
    const payload = {
      userId: id,
    };
    const user_access_token = await this.redisService.get(`USER_ACCESS_TOKEN:${id}`);
    if (user_access_token) {
      const refreshToken = await this.redisService.get(`USER_REFRESH_TOKEN:${id}`);
      await this.userService.updateUserLoginInfo(id, req);
      return {
        accessToken: user_access_token,
        refreshToken,
      };
    }
    const token = this.generateToken(payload);
    // 刷新用户信息
    if (!token) throw new CustomException(ErrorCode.ERR_11009);
    const res = await this.userService.refreshUserInfo(id);
    // 更新用户登录信息
    if (!res) throw new CustomException(ErrorCode.ERR_11009);
    await this.userService.updateUserLoginInfo(id, req);
    return token;
  }

  // 生成token
  async generateToken(payload: any) {
    const accessToken = this.jwtService.sign(payload, {
      expiresIn: process.env.ACCESSTOKEN_EXPIRESIN,
    });
    // 生成refreshToken
    payload.accessToken = accessToken;
    const refreshToken = this.jwtService.sign(payload, {
      expiresIn: process.env.REFRESHTOKEN_EXPIRESIN,
    });
    await this.redisService.set(
      `USER_ACCESS_TOKEN:${payload.userId}`,
      accessToken,
      parseInt(process.env.ACCESSTOKEN_EXPIRESIN, 10),
    );
    // 存储refreshToken
    await this.redisService.set(
      `USER_REFRESH_TOKEN:${payload.userId}`,
      refreshToken,
      parseInt(process.env.REFRESHTOKEN_EXPIRESIN, 10),
    );
    return {
      accessToken,
      refreshToken,
    };
  }

  // 退出登录
  async logout(user: any) {
    // 删除redis中的token
    if (user.userId) {
      await Promise.all([
        this.redisService.del(`USER_ACCESS_TOKEN:${user.userId}`),
        this.redisService.del(`USER_REFRESH_TOKEN:${user.userId}`),
      ]);
      return true;
    }
    return false;
  }

  // 无感token刷新
  async refreshToken(data: any) {
    const payload = this.jwtService.verify(data.refreshToken);
    if (!payload) throw new CustomException(ErrorCode.ERR_11010);
    const refreshTokenFromRedis = await this.redisService.get(`USER_REFRESH_TOKEN:${payload.userId}`);
    console.log('refreshTokenFromRedis', refreshTokenFromRedis);
    console.log('payload accessToken',payload.accessToken);
    if (refreshTokenFromRedis !== data.refreshToken) throw new CustomException(ErrorCode.ERR_11010);
    const newPayload = {
      userId: payload.userId,
    };
    await this.userService.refreshUserInfo(payload.userId);
    return this.generateToken(newPayload);
  }
}
